package com.dkts.oil.test;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.apache.commons.math3.ml.clustering.DBSCANClusterer;
import org.apache.commons.math3.ml.clustering.Cluster;
import org.apache.commons.math3.ml.clustering.DoublePoint;

import java.io.*;
import java.util.*;

public class AISFleetAnalyzer {

    // 设定最大距离阈值和最大时间间隔
    private static final double DISTANCE_THRESHOLD = 5000; // 30公里
    private static final long TIME_THRESHOLD = 40 * 60 * 1000; // 40分钟

    public static void main(String[] args) throws Exception {
        File csvFile = new File("C:\\Users\\heyou\\Documents\\WeChat Files\\wxid_86da35bc9zvi21\\FileStorage\\File\\2025-05\\c9a6717b7d2f5293cf7cd2ed05a0494c_2e2437ef9cd58c0d39af05569deeb4be_8.csv");
        Reader reader = new FileReader(csvFile);

        CSVParser parser = CSVFormat.DEFAULT
                .withFirstRecordAsHeader()
                .parse(reader);

        // 解析 CSV
        Map<String, List<CSVRecord>> mmsiMap = new HashMap<>();
        for (CSVRecord record : parser) {
            String mmsi = record.get("mmsi");
            if (!mmsiMap.containsKey(mmsi)) {
                mmsiMap.put(mmsi, new ArrayList<>());
            }
            mmsiMap.get(mmsi).add(record);
        }

        // DBSCAN 聚类
        List<DoublePoint> points = new ArrayList<>();
        Map<String, List<CSVRecord>> clusteredRecords = new HashMap<>();

        // 将轨迹数据转换为 DBSCAN 可用的 DoublePoint 格式
        for (Map.Entry<String, List<CSVRecord>> entry : mmsiMap.entrySet()) {
            List<CSVRecord> records = entry.getValue();
            for (CSVRecord record : records) {
                double lat = Double.parseDouble(record.get("lat"));
                double lon = Double.parseDouble(record.get("lon"));
                // 用 lat, lon 创建 DoublePoint
                points.add(new DoublePoint(new double[]{lat, lon}));
            }
        }

        // 执行 DBSCAN 聚类
        DBSCANClusterer<DoublePoint> clusterer = new DBSCANClusterer<>(DISTANCE_THRESHOLD, 10);
        List<Cluster<DoublePoint>> clusters = clusterer.cluster(points);

        // 根据聚类结果创建每个编队的文件夹
        for (Cluster<DoublePoint> cluster : clusters) {
            String folderName = "fleet_" + cluster.getPoints().size();
            File folder = new File(folderName);
            if (!folder.exists()) {
                folder.mkdir();
            }

            // 创建一个集合，存储所有轨迹点
            List<double[]> trajectoryPoints = new ArrayList<>();
            for (DoublePoint point : cluster.getPoints()) {
                trajectoryPoints.add(point.getPoint());
            }

            // 为每个编队输出一个GeoJSON文件
            for (Map.Entry<String, List<CSVRecord>> entry : mmsiMap.entrySet()) {
                String mmsi = entry.getKey();
                List<CSVRecord> records = entry.getValue();
                ObjectMapper mapper = new ObjectMapper();
                ObjectNode featureCollection = mapper.createObjectNode();
                featureCollection.put("type", "FeatureCollection");
                ArrayNode features = mapper.createArrayNode();

                // 创建一个新的 LineString，将轨迹点连接起来
                ObjectNode feature = mapper.createObjectNode();
                feature.put("type", "Feature");

                ObjectNode geometry = mapper.createObjectNode();
                geometry.put("type", "LineString");
                ArrayNode coordinates = mapper.createArrayNode();

                // 将轨迹点（lat, lon）添加到 LineString 的坐标数组中
                for (CSVRecord record : records) {
                    double lat = Double.parseDouble(record.get("lat"));
                    double lon = Double.parseDouble(record.get("lon"));
                    ArrayNode point = mapper.createArrayNode();
                    point.add(lon);
                    point.add(lat);
                    coordinates.add(point);
                }

                geometry.set("coordinates", coordinates);
                feature.set("geometry", geometry);

                // 设置属性信息
                ObjectNode properties = mapper.createObjectNode();
                properties.put("mmsi", mmsi);

                feature.set("properties", properties);
                features.add(feature);

                featureCollection.set("features", features);

                // 输出 GeoJSON 文件
                FileWriter writer = new FileWriter(folder.getPath() + "\\" + mmsi + ".geojson");
                mapper.writerWithDefaultPrettyPrinter().writeValue(writer, featureCollection);
                System.out.println("输出文件：" + folder.getPath() + "\\" + mmsi + ".geojson");
            }
        }
    }
}
